﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IcarusProject.MazeGen
{
    public class Maze
    {
        #region Attributs
        private int _width;
        private int _height;
        private Cell[,] _map;
        private Random _randomGen;
        private int[,] _labyrinthe;

        #endregion

        #region Constructeur
        public Maze(int width, int height)
        {
            _width = width;
            _height = height;
            _randomGen = new Random();
            _map = new Cell[_width, _height];
            _labyrinthe = new int[1 + 2 * _width, 1 + 2 * _height];
        }
        #endregion

        #region Proprietes
        public int MapWidth
        {
            get { return 1 + 2 * _width; }
        }

        public int MapHeight
        {
            get { return 1 + 2 * _height; }
        }

        public int this[int i, int j]
        {
            get { return _labyrinthe[i, j]; }
        }
        #endregion

        #region Methodes
        public Maze Init()
        {
            for (int i = 0; i < _width; ++i)
                for (int j = 0; j < _height; ++j)
                    _map[i, j] = new Cell(j * _width + i);
            return this;
        }

        public Maze Build()
        {
            int nbCellVisited = 0;
            while (nbCellVisited < _width * _height - 1)
            {
                //On tire une case au hasard
                int x = _randomGen.Next(_width);
                int y = _randomGen.Next(_height);

                //On tire une direction au hasard
                int dir = _randomGen.Next(2);

                //Case voisine
                //dir = 0 => en bas
                //dir = 1 => a droite
                int xn = x + dir;
                int yn = y + (1 - dir);

                if (xn < _width && yn < _height)
                {
                    int idCase = _map[x, y].ID;
                    int idNCase = _map[xn, yn].ID;

                    //On verifie les Id
                    if (idCase != idNCase)
                    {
                        if (dir == 0) //Mur du bas
                            _map[x, y].DeleteBottomWall();
                        else
                            _map[x, y].DeleteRightWall();

                        //On parcours le tableau pour changer l'Id de l'ancien groupe
                        for (int i = 0; i < _width; ++i)
                            for (int j = 0; j < _height; ++j)
                                if (_map[i, j].ID == idNCase)
                                    _map[i, j].ID = idCase;



                        nbCellVisited++;
                    }
                }
            }
            return this;
        }

        public void FillMap(int floorId, int hWallId, int vWallId, int cId)
        {
            _labyrinthe[0, 0] = cId;

            for (int i = 1; i < MapWidth; ++i)
                _labyrinthe[i, 0] = hWallId;

            for (int j = 1; j < MapHeight; ++j)
                _labyrinthe[0, j] = vWallId;

            for (int i = 0; i < _width; ++i)
                    {
                        for (int j = 0; j < _height; ++j)
                        {
                            int x = 1 + 2 * i;
                            int y = 1 + 2 * j;

                            _labyrinthe[x, y] = floorId;
                            _labyrinthe[x + 1, y + 1] = cId;

                            if (_map[i, j].RightWall)
                                _labyrinthe[x + 1, y] = hWallId;
                            else
                                _labyrinthe[x + 1, y] = floorId;

                            if (_map[i, j].BottomWall)
                                _labyrinthe[x, y + 1] = vWallId;
                            else
                                _labyrinthe[x, y + 1] = floorId;

                        }
                    }
        }
        #endregion
    }
}
